package com.token.sysflow.service;

import com.token.sql.IntegrateSql;
import com.token.sysflow.bean.*;
import com.token.sysflow.enumerate.StepTypeEnum;

import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Objects;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.token.base.FuncUtil;
import com.token.base.Pl;
import com.token.sysflow.hander.AppInfo;

/**
 * 写流程信息
 *
 * @author chenjianxiong
 */
public class FlowInfoWrite {
    private final String datetime;
    private String user;
    private final int sysid;

    public FlowInfoWrite() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        datetime = sdf.format(new Date());
        sysid = Pl.getSysId();
    }

    /**
     * @param F    类库
     * @param iSql 类库
     * @throws Exception
     */
    public void writeData(FuncUtil F, IntegrateSql iSql) throws Exception {
        user = F.getCurPersonNumber();
        JSONObject json = JSONObject.parseObject(F.getUrlQueryString("json"));
        //JSON.parse(F.getURLQueryString("json"));
        JSONObject flow = json.getJSONObject("flow");
        String keyValue = flow.getString("FlowId");
        FlowFlowInfo dao = new FlowFlowInfo(iSql);

        FlowFlowInfoVth flowInfoVth = new FlowFlowInfoVth(iSql);
        dao.setInsertOrUpdateRs(keyValue);
//        boolean isDefaultFlow = false;
        if (!dao.isUpdate()) {
            dao.setSysId(sysid); //租户ID //json.getIntValue("SysId")
            dao.setSysAddTime(datetime); //创建时间
            dao.setSysAddUser(user); //创建人
            //}else{
//            isDefaultFlow = true;
        }else{
            iSql.deleteData(flowInfoVth.getTableName(), "flowid", dao.getFlowId());
        }

        dao.setSysEditTime(datetime); //修改时间
        dao.setSysEditUser(user); //修改人
        dao.setFlowId(keyValue); //流程ID
        dao.setIsActive(flow.getString("IsActive")); //激活流程
        dao.setIsDefault(flow.getString("IsDefault")); //默认流程
        dao.setFlowArea(flow.getString("FlowArea")); //使用范围

        dao.setFlowName(flow.getString("FlowName")); //流程名称
        dao.setFlowVersion(flow.getString("FlowVersion")); //流程版本
        dao.setFlowDesc(flow.getString("FlowDesc")); //流程描述
        dao.setFlowCode(flow.getString("FlowCode")); //流程编码
        dao.setFlowCode1(flow.getString("FlowCode1")); //yyyyMMdd
        dao.setFlowCode2(flow.getString("FlowCode2")); //流水号位数


        dao.setAppKeyId(getSelectTreeValue(flow, "AppKeyId")); //流程应用
        dao.setJsonNode(json.getJSONObject("nodes").toJSONString()); //节点数据
        dao.executeUpdate();


        flowInfoVth.setInsert();
        flowInfoVth.setFlowId(dao.getFlowId());
        this.approverVth(flowInfoVth,flow,"UsePowerOrg");
        this.approverVth(flowInfoVth,flow,"FlowPosts");
        this.approverVth(flowInfoVth,flow,"FlowDepartment");
        this.approverVth(flowInfoVth,flow,"FlowCompany");
        this.approverVth(flowInfoVth,flow,"FlowRoles");
        this.approverVth(flowInfoVth,flow,"FlowOrgReader");


        //写入应用的默认流程
        if (flow.getString("IsDefault").equals("1")) {
            AppInfo appInfo = new AppInfo(iSql, dao.getAppKeyId());
            if (appInfo.isHas()) {
                String old = appInfo.getDefaultFlowId();
                if (!old.equals(dao.getFlowId())) {
                    appInfo.setUpdateCur();
                    appInfo.setDefaultFlowId(dao.getFlowId());
                    appInfo.executeUpdate();

                    //取消旧的默认流程
                    if (!Objects.requireNonNull(old).equals("")) {
                        if(dao.initParamToRs(old)) {
                            dao.setUpdateCur();
                            dao.setIsDefault("0");
                            dao.executeUpdate();
                            dao.close();
                        }
                    }
                }
            }
        }

        writeDataStep(iSql, json.getJSONArray("steps"), keyValue);
        writeDataPath(iSql, json.getJSONArray("paths"), keyValue);
    }

    /**
     * @param json
     * @param keyName
     * @return String
     */
    private String getSelectTreeValue(JSONObject json, String keyName) {
        try {
            JSONObject app = json.getJSONObject(keyName);
            return app.getString("value");
        } catch (Exception e) {
            return json.getString(keyName);
        }
    }

    /**
     * @param iSql   类库
     * @param paths
     * @param flowId
     * @throws SQLException
     */
    private void writeDataPath(IntegrateSql iSql, JSONArray paths, String flowId) throws SQLException {
        FlowPathInfo dao = new FlowPathInfo(iSql);
        for (int i = 0; i < paths.size(); i++) {
            JSONObject json = paths.getJSONObject(i);
            String pathId = json.getString("PathId");
            dao.setInsertOrUpdateRs(pathId);
            dao.setPathId(json.getString("PathId")); //流向ID
            dao.setFlowId(flowId); //流程ID

            if (dao.isUpdate()) {
                dao.setSysEditTime(datetime); //修改时间
                dao.setSysEditUser(user); //修改人
            } else {
                dao.setSysId(sysid); //租户ID //json.getIntValue("SysId")
                dao.setSysAddTime(datetime); //创建时间
                dao.setSysAddUser(user); //创建人
                dao.setSysEditTime(datetime); //修改时间
                dao.setSysEditUser(user); //修改人
            }
            dao.setSerialNumber(json.getIntValue("SerialNumber")); //序号
            dao.setFromStepId(json.getString("FromStepId")); //开始环节ID
            dao.setToStepId(json.getString("ToStepId")); //目标环节ID
            dao.setPathName(json.getString("PathName")); //流向名称
            dao.executeUpdate();
        }
        dao.close();
    }

    /** 分号合并JSONArray
     * @param arr
     * @return
     */
    private String joinArray(JSONArray arr) {
        if(arr == null){
            return "";
        }
        StringBuilder str = new StringBuilder(50);
        boolean b = false;
        for (int i = 0; i < arr.size(); i++) {
            if (b) {
                str.append(";");
            } else {
                b = true;
            }
            str.append(arr.get(i));
        }
        return str.toString();
    }

    /**
     * @param iSql   类库
     * @param steps
     * @param flowid
     * @throws SQLException
     */
    private void writeDataStep(IntegrateSql iSql, JSONArray steps, String flowid) throws SQLException {
        FlowStepBasic basic = new FlowStepBasic(iSql);
        FlowStepControl control = new FlowStepControl(iSql);
        FlowStepSwitchFunc switchFunc = new FlowStepSwitchFunc(iSql);
        FlowStepApprover approver = new FlowStepApprover(iSql);
        FlowStepApproverVth vth = new FlowStepApproverVth(iSql);
        FlowStepSubflow subflow = new FlowStepSubflow(iSql);
        FlowStepSubflowSub flowStepSubflowSub = new FlowStepSubflowSub(iSql);
        FlowStepNotifySub flowStepNotifySub = new FlowStepNotifySub(iSql);
        FlowStepSubflowVth subflowVth = new FlowStepSubflowVth(iSql);
        FlowStepNotifyVth notifySub = new FlowStepNotifyVth(iSql);

        iSql.deleteData(vth.getTableName(), "flowid", flowid);
        iSql.deleteData(subflowVth.getTableName(), "flowid", flowid);
        iSql.deleteData(notifySub.getTableName(), "flowid", flowid);
        vth.setInsert();
        vth.setFlowId(flowid);
        notifySub.setInsert();
        notifySub.setFlowId(flowid);
        subflowVth.setInsert();
        subflowVth.setFlowId(flowid);

        for (int i = 0; i < steps.size(); i++) {
            JSONObject json = steps.getJSONObject(i);
            String stepid = json.getString("StepId");

            basic.setInsertOrUpdateRs(stepid);
            if (basic.isUpdate()) {
                basic.setSysEditTime(datetime); //修改时间
                basic.setSysEditUser(user); //修改人
            } else {
                basic.setSysId(sysid); //租户ID //json.getIntValue("SysId")
                basic.setSysAddTime(datetime); //创建时间
                basic.setSysAddUser(user); //创建人
                basic.setSysEditTime(datetime); //修改时间
                basic.setSysEditUser(user); //修改人
            }

            basic.setFlowId(flowid); //流程ID
            basic.setStepId(stepid); //环节ID
            basic.setStepType(json.getString("StepType")); //环节类型
            basic.setStepName(json.getString("StepName")); //环节名称
            basic.setStepNumber(json.getIntValue("StepNumber")); //序号
            basic.setStdHours(json.getIntValue("StdHours")); //标准办理时间(h)
            //			basic.setAgentsName(json.getString("AgentsName")); //提交后运行
            //			basic.setAgentReBefore(json.getString("AgentReBefore")); //退回本环节
            basic.setStepDesc(json.getString("StepDesc")); //环节描述
            basic.setForkCondition(json.getString("ForkCondition")); //决策条件
            basic.setUseNotify(json.getString("UseNotify")); //知会开关
            basic.setNotifyWay(joinArray(json.getJSONArray("NotifyWay"))); //知会方式
            basic.setHttpSubmitBefore(json.getString("HttpSubmitBefore")); //提交前接口
            basic.setHttpSubmitAfter(json.getString("HttpSubmitAfter")); //提交后接口
            basic.setHttpReturnBefore(json.getString("HttpReturnBefore")); //退回后接口
            basic.executeUpdate();
            //joinArray(json.getJSONArray("NotifyWay"))
            //
            control.setInsertOrUpdate(stepid);
            control.setStepId(stepid); //环节ID
            control.setFlowId(flowid); //流程ID
            control.setDefaultOpinion(json.getString("DefaultOpinion")); //默认意见
            control.setEditFields(json.getString("EditFields")); //可编辑字段
            control.setNeedFields(json.getString("NeedFields")); //必填字段
            control.setFocusFields(json.getString("FocusFields")); //关注字段
            control.setModifyFields(json.getString("ModifyFields")); //记录字段

            control.executeUpdate();


            switchFunc.setInsertOrUpdate(stepid);
            switchFunc.setStepId(stepid); //环节ID
            switchFunc.setFlowId(flowid); //流程ID

            if (basic.getStepType().equals(StepTypeEnum.STEPTYPE_TASK_HQ.getTypeKey())) {
                switchFunc.setSelectWay("1"); //选择方式
            } else if (basic.getStepType().equals(StepTypeEnum.STEPTYPE_TASK_HS.getTypeKey())) {
                switchFunc.setSelectWay("1"); //选择方式
            } else {
                switchFunc.setSelectWay(json.getString("SelectWay")); //选择方式
            }

            switchFunc.setCanPrint(json.getString("CanPrint")); //可否打印
            switchFunc.setCanUpload(json.getString("CanUpload")); //可否上传附件
            switchFunc.setAutoWay(json.getString("AutoWay")); //相同审批跳转
            switchFunc.setCanReturn(json.getString("CanReturn")); //可否退回
            switchFunc.setSelectWayCheck(json.getString("SelectWayCheck")); //选择方式1
            //System.out.print("NO:" + json.getString("NoChecked"));
            switchFunc.setNoChecked(json.getString("NoChecked")); //选择方式2
            switchFunc.setCanReturnCheck(json.getString("CanReturnCheck")); //退回选项
            switchFunc.setCanOther(json.getString("CanOther")); //可否转审
            switchFunc.setCanCC(json.getString("CanCC")); //可否抄送
            switchFunc.setCanOrgSign(json.getString("CanOrgSign")); //可否组织会签
            switchFunc.setCanCame(json.getString("CanCame")); //可否组织会审
            switchFunc.setCanOver(json.getString("CanOver")); //可否终止
            switchFunc.setCanBack(json.getString("CanBack")); //可否取回
            switchFunc.setCanSubmitRePerson(json.getString("CanSubmitRePerson")); //提交退回人

            switchFunc.setNeedAttachmentCheck(json.getString("NeedAttachmentCheck"));
            switchFunc.setNeedAttachmentTip(json.getString("NeedAttachmentTip")); //附件必填提示
            switchFunc.setCanDownload(json.getString("CanDownload")); //可否下载附件
            switchFunc.setAutoWanType(json.getString("AutoWanType")); //智能跳转选项
            switchFunc.setCanWordExcel(json.getString("CanWordExcel")); //word/Excel操作
            switchFunc.executeUpdate();

            //------写入办理人多值 --这个位置不要改动----
            vth.setStepId(stepid); //环节ID
            approverVth(vth, json, "ApproverPeople");
            approverVth(vth, json, "ApproverPost");
            approverVth(vth, json, "ApproverRole");
            approverVth(vth, json, "ApproverField");
            //------写入办理人多值 ------

            approver.setInsertOrUpdate(stepid);
            approver.setStepId(stepid); //环节ID
            approver.setFlowId(flowid); //流程ID
            approver.setApproverType(json.getIntValue("ApproverType"));
//            if (b1) {
//                approver.setApproverType(1); //办理人类型：1人员
//            } else if (b2) {
//                approver.setApproverType(2); //办理人类型：2岗位
//            } else if (b3) {
//                approver.setApproverType(3); //办理人类型：3角色
//            } else if (b4) {
//                approver.setApproverType(4); //办理人类型：4字段
//            }
            approver.setRoleOrPerson(json.getString("RoleOrPerson")); //3.角色组合选择
            approver.setPreHandlerSw(json.getBooleanValue("PreHandlerSw")); //5.环节审批人开关
            approver.setPreHandler(json.getString("PreHandler")); //5.环�谏笈�
            approver.setDeptLeaderSw(json.getBooleanValue("DeptLeaderSw")); //6.组织架构开关
            approver.setDeptLeaderTy(json.getIntValue("DeptLeaderTy")); //组织架构1
            approver.setDeptLeader(json.getIntValue("DeptLeader")); //组织架构2
            //			approver.setUpPosition(json.getBooleanValue("UpPosition")); //7.职位上下级
            //json.getString("ApproverFunc")
            approver.setApproverFunc(this.getSelectTreeValue(json,"ApproverFunc")); //8.办理函数
            approver.setApproverFuncTy(json.getIntValue("ApproverFuncTy")); //办理函数1
            approver.setApproverFuncOrg(json.getIntValue("ApproverFuncOrg")); //办理函数2
            approver.setNotesFormular(json.getString("NotesFormular")); //9.公式计算
            approver.setHSway(json.getString("HSway")); //会审策略
            approver.setHSnum(json.getIntValue("HSnum")); //指定通过数量
            approver.setKeyUser(json.getString("KeyUser")); //关键办理人
            approver.executeUpdate();


            JSONArray notifyArr = json.getJSONArray("Notify");
            if (notifyArr != null) {

                for (int j = 0; j < notifyArr.size(); j++) {
                    JSONObject notify = notifyArr.getJSONObject(j);
                    String keyid = notify.getString("key");
                    flowStepNotifySub.setInsertOrUpdate(keyid);
                    flowStepNotifySub.setNotifyID(keyid); //主键
                    flowStepNotifySub.setStepId(stepid); //环节ID
                    flowStepNotifySub.setFlowId(flowid); //流程ID
                    flowStepNotifySub.setExtWay(notify.getString("ExtWay")); //执行方式
                    flowStepNotifySub.setNotifySubject(notify.getString("NotifySubject")); //知会主题
                    flowStepNotifySub.setNotifyContext(notify.getString("NotifyContext")); //知会内容
                    flowStepNotifySub.setNotifyObject(notify.getString("NotifyObject")); //知会对象

                    flowStepNotifySub.setCreOrApply(this.joinArray(notify.getJSONArray("CreOrApply"))); //起草人/申请人
                    flowStepNotifySub.setNotifyFieldName(notify.getString("NotifyFieldName")); //指定人域
                    flowStepNotifySub.setConditional(notify.getString("Conditional")); //条件判断公式
//                    flowStepNotifySub.setIsInConfig(notify.getString("IsInConfig")); //启用公式
//                    flowStepNotifySub.setSortby(""); //排列次序
                    flowStepNotifySub.setConditionalApi(notify.getString("ConditionalApi")); //条件判断接口
                    flowStepNotifySub.executeUpdate();

                    approverVth(notifySub, notify, keyid, "NotifyPosts");
                    approverVth(notifySub, notify, keyid, "NotifyDepartment");
                }

            }


            if ("task_zlc".equals(json.getString("StepType"))) { // 子流程
                subflow.setInsertOrUpdate(stepid);
                subflow.setStepId(stepid); //环节ID
                subflow.setFlowId(flowid); //流程ID
                subflow.setSubflowReSave(json.getString("SubflowReSave")); //初始化子流程
                subflow.setSubflowSelect(json.getString("SubflowSelect")); //可选择子流程
                subflow.setSubflowShowALL(json.getString("SubflowShowALL")); //是否全部显示
                subflow.executeUpdate();

                JSONArray arr = json.getJSONArray("SubFlow");
                if (arr != null) {
                    for (int j = 0; j < arr.size(); j++) {
                        JSONObject sub = arr.getJSONObject(j);
                        String keyid = sub.getString("key");
                        flowStepSubflowSub.setInsertOrUpdate(keyid);
                        flowStepSubflowSub.setSubFlowID(keyid); //主键
                        flowStepSubflowSub.setStepId(stepid); //环节ID
                        flowStepSubflowSub.setFlowId(flowid); //流程ID
                        flowStepSubflowSub.setSubFlowName(sub.getString("SubFlowName")); //子流程名称
                        flowStepSubflowSub.setInnerFormName(sub.getString("InnerFormName")); //指定子表单名
                        flowStepSubflowSub.setSubFlowFlag(sub.getString("SubFlowFlag")); //子流程标识
                        flowStepSubflowSub.setSelectSubFlow(sub.getString("SelectSubFlow")); //指定子流程
                        flowStepSubflowSub.setReturnResult(sub.getString("ReturnResult")); //执行条件
                        flowStepSubflowSub.setFieldForWrite(sub.getString("FieldForWrite")); //回写字段
                        flowStepSubflowSub.setSubFlowFile(sub.getString("SubFlowFile")); //表单字段
//                        flowStepSubflowSub.setSortby(sub.getString("Sortby")); //排列次序
                        flowStepSubflowSub.executeUpdate();


                        approverVth(subflowVth, sub, keyid, "ApproverPeoples");
                        approverVth(subflowVth, sub, keyid, "ApproverRoles");
                    }
                }

            } else {
                iSql.deleteData(subflow.getTableName(), subflow.getKeyName(), stepid);
            }
        }
        vth.close();
        basic.close();
        approver.close();
        control.close();
        switchFunc.close();
        subflow.close();
    }

    /**
     * @param vth
     * @param json
     * @param type
     * @return
     * @throws SQLException
     */
    private boolean approverVth(FlowFlowInfoVth vth, JSONObject json, String type) throws SQLException {

        try {
            JSONArray arr = json.getJSONArray(type);
            if (arr != null) {
                vth.setFieldName(type); //字段类型
                JSONObject labelObject;
                for (int i = 0; i < arr.size(); i++) {
                    labelObject = arr.getJSONObject(i);
                    vth.setValue(labelObject.getString("value")); //值
                    vth.setLabel(labelObject.getString("label")); //Label
                    vth.addBatch();
                }
                vth.executeBatch();
                return true;
            } else {
                System.out.println("--->" + type);
                return false;
            }
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * @param vth
     * @param json
     * @param type
     * @return
     * @throws SQLException
     */
    private boolean approverVth(FlowStepApproverVth vth, JSONObject json, String type) throws SQLException {

        try {
            JSONArray arr = json.getJSONArray(type);
            if (arr != null) {
                vth.setFieldName(type); //字段类型
                JSONObject labelObject;
                for (int i = 0; i < arr.size(); i++) {
                    labelObject = arr.getJSONObject(i);
                    vth.setValue(labelObject.getString("value")); //值
                    vth.setLabel(labelObject.getString("label")); //Label
                    vth.addBatch();
                }
                vth.executeBatch();
                return true;
            } else {
                System.out.println("--->" + type);
                return false;
            }
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * @param notifyVth
     * @param json
     * @param keyid
     * @param type
     * @return
     * @throws SQLException
     */
    private boolean approverVth(FlowStepNotifyVth notifyVth, JSONObject json, String keyid, String type) throws SQLException {
        try {
            JSONArray arr = json.getJSONArray(type);
            if (arr != null) {
                notifyVth.setFieldName(type); //字段类型
                notifyVth.setNotifyID(keyid);
                JSONObject labelObject;
                for (int i = 0; i < arr.size(); i++) {
                    labelObject = arr.getJSONObject(i);
                    notifyVth.setValue(labelObject.getString("value")); //值
                    notifyVth.setLabel(labelObject.getString("label")); //Label
                    notifyVth.addBatch();
                }
                notifyVth.executeBatch();
                return true;
            } else {
                System.out.println("--->" + type);
                return false;
            }
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * @param subflowVth
     * @param json
     * @param keyid
     * @param type
     * @return
     * @throws SQLException
     */
    private boolean approverVth(FlowStepSubflowVth subflowVth, JSONObject json, String keyid, String type) throws SQLException {
        try {
            JSONArray arr = json.getJSONArray(type);
//            System.out.println("arr = " + arr);
            if (arr != null) {
                subflowVth.setFieldName(type); //字段类型
                subflowVth.setSubFlowID(keyid);
                JSONObject labelObject;
                for (int i = 0; i < arr.size(); i++) {
                    labelObject = arr.getJSONObject(i);
                    subflowVth.setValue(labelObject.getString("value")); //值
                    subflowVth.setLabel(labelObject.getString("label")); //Label
                    subflowVth.addBatch();
                }
                subflowVth.executeBatch();
                return true;
            } else {
                System.out.println("--->" + type);
                return false;
            }
        } catch (Exception e) {
            return false;
        }
    }

}
